Tencent Linux(TencentOS) 十年云原生迭代演进之路
The following article is from 腾讯云原生 Author 蒋彪
导语
TencentOS Server (又名 Tencent Linux 简称 Tlinux) 是腾讯针对云的场景研发的 Linux 操作系统,提供了专门的功能特性和性能优化,为云服务器实例中的应用程序提供高性能,且更加安全可靠的运行环境。Tencent Linux 使用免费,在 CentOS(及兼容发行版)上开发的应用程序可直接在 Tencent Linux 上运行,用户还可持续获得腾讯云的更新维护和技术支持。
TencentOS 在腾讯内部已经经历了超过10年的迭代和演进,承载支撑了腾讯所有业务,商用部署节点超300w,经受住了海量复杂业务模型在极端场景中的极限考验。
通用 OS 架构
传统 OS 的定义(盗用经典教科书内容):
操作系统是控制应用程序执行的程序,是应用程序和计算机(硬件)间的接口。
操作系统有3个目标:
方便:让计算机更易于使用
有效:允许以更有效的方式使用计算机资源
扩展:允许在不影响服务的前提下,有效的开发、测试和引入新的系统功能
传统通用 OS(Linux) 的典型架构设计如上,操作系统中包含了为实现上述3个目标而提供的各种功能模块和接口,总体上,分为两大部分:
内核:提供底层硬件(计算机)的基本抽象,不同的内核模块提供不同的硬件管理或相关的辅助功能,通过系统调用向上层应用提供服务。
基础库和相关服务组件(用户态):为真实业务运行提供基础运行环境
IaaS 场景中的 OS
IaaS 场景中,OS 主要用于为云主机(虚拟机)提供运行环境,在 IaaS 场景中,OS 中运行的任务类型和数量可控,场景相对通用场景简单很多。任务类型基本就只有如下几类:
VM 相关线程(通常为 Qemu + Vcpu 线程)
各种控制面的管理 Agents
OS 自身必须的一些控制线程(比如 Per-cpu Workers)
IaaS 场景中,为使虚拟机性能无限接近(甚至超越)物理机,通常会考虑做减法,通过无限减少虚拟化、OS 层面的开销来提升性能,常用的一些典型手段如:
CPU 层面的绑核
内存层面的预分配
IO 层面的各种 Bypass Kernel 技术
对于 OS 来说,最终的结果是:
OS 越来越薄,最终可能会消失
换个角度看 OS (云原生角度)
当云原生浪潮袭来,换个角度(云原生角度)再去审视 OS 时,看到的又是不一样的视图。云原生场景对 OS 提出了新的挑战,也为 OS 相关技术的进一步发展和演进注入了新的动力。
云原生场景中,OS 为不同类型的应用(Apps,Containers,Functions,Sandboxes),提供底层支撑和服务。此时,相比 IaaS 场景,最明显的差别在于:
应用和系统的边界大幅上移,应用之下皆为 OS
对于 OS 来说,最终的结果是:
OS 越来越厚(孕育无限可能),与 IaaS 场景形成鲜明对比
TencentOS For 云原生
在云原生浪潮席卷的行业大背景下,伴随着腾讯自身的各种业务架构的快速转身,业务的容器化、微服务化、Serverless 化,对底层的基础设施(包括核心的 OS )提出了新的挑战和要求,TencentOS 也随之迅速转型,针对腾讯自身的云原生场景和需求,进行了深度的重构和重新设计,全面拥抱云原生,向云原生 OS 的目标一步步迈进。
总体架构
TencentOS (当前)主要实现( Kernel 层)了如下云原生 Features (后文展开)
云原生调度器 - Tencent Could Native Scheduler(TCNS)
云原生资源 QoS - RUE
Quality Monitor
云原生 SLI
Cgroupfs
云原生调度器 - Tencent Could Native Scheduler(TCNS)
TCNS 是 TencentOS 针对云原生场景,提供的内核调度器整体解决方案,可以覆盖容器、安全容器和通用场景,对于多优先级业务混部中对 CPU 隔离的需求,以及对实时性/稳定性有极致要求的业务场景,有奇效。有关混部场景中对于CPU隔离性的需求和可能的解决方案,本篇《混部之殇-论云原生资源隔离技术之CPU隔离(一)》有详细解说,有关内核调度器的实时性保障的相关技术讨论,在后续的 os 系列文章中会再讲到,请陆续关注。
TCNS 主要包括3个模块:
BT Scheduler
VMF Scheduler
ECFS
BT Scheduler
BT Scheduler 是 TencentOS 针对(容器)混部场景的 CPU 隔离设计的新的调度类,位置如下图所示:
其核心设计为:全新设计新的调度类,优先级比默认的 CFS 低,仅当没有其他更高优先级的任务运行时才能运行,专用于运行离线任务(在线任务使用 CFS 类)。
如此设计的核心收益为:可实现在线业务对离线业务的绝对抢占,在混部场景中可以得到近乎完美的 CPU 隔离效果。
BT 调度类本身还是一个功能完整的新调度类,在 BT 调度类内可以提供类似 CFS 的功能全集。
除此之外,BT 调度类还实现了如下诸多特性:
有关 BT 的其他信息,可以戳如下链接了解:
【https://cloud.tencent.com/developer/article/1519558】
注:内容虽然有些老,新版本已经迭代了几轮,供参考。有关 BT 的最新介绍,也会在后续陆续推出相应文章,敬请期待。
VMF Scheduler
VMF (VM First) 调度器,是 TencentOS 针对安全容器场景(和虚拟机场景)专门设计的内核调度器解决方案(重新实现了一个全新的内核调度器)。
重写调度器的主要背景是:现有的 CFS 调度器基于“完全公平”的原则,无法保证虚拟机(安全容器)线程调度的实时性。
VMF 的核心设计包括:
不公平的调度器,通过将 CPU 资源向虚拟机进程倾斜,从而保障虚拟机(安全容器)线程能优先得到调度
基于任务类型进行调度,而没有细粒度的优先级。相比之下,我们认为,CFS 的优先级并不能准确的描述不同进程的运行特征,典型的就是内核线程,这类进程的特征很明显,首先他很重要,其次他的单次执行时间很短,但却很难定义他们的优先级,高低都不合适,仅仅通过优先级并不能准确描述他们运行行为。在 VMF 中,我们通过对不同进程的特征进行画像和建模,将所有进程进行分类,并对不同类型进程设计精细的调度策略,可以满足云原生场景下,对实时性的极致需求。
单向激进抢占,即 VM 进程可以在任何情况下尽快抢占其他任务,而反过来则不行,这样可以在不损害调度器的吞吐性能的情况下,最大程度保障 VM 进程的实时性。
另外,我们还针对其他的场景和需求设计了许多其他的特性,篇幅有限,无法展开详述,计划后续另起话题单独介绍。
整体来看,通过自研的VMF调度器,我们可以获得几个关键收益:
极致调度延迟指标(实时性好),极端情况下的最大延迟都在微妙级
新调度器相比 CFS ,要轻量许多,整体代码量不到 CFS 的 1/3
在存在部分干扰的情况下,保证虚拟机(安全容器)线程的实时性
基于 VMF 的分类设计,可以实现对不同类型进程提供不同级别的 CPU QoS 保障
通过完全自研的调度器,可以做很多很炫的、平时不敢想象的定制。如果大家有优化 CFS 的经验,应该都能体会,要在 CFS 上做定制能有多难受。
有关 VMF 的说明,也计划另文讨论,也请期待。另 OS2ATC 2020 大会中的虚拟化专场,主题:《Tianus Hypervisor - “零损耗”的腾讯云轻量级虚拟化技术》中也有部分说明
【https://www.bilibili.com/video/BV1Ky4y1m7yr/?spm_id_from=333.788.recommend_more_video.1】
< 注:1:24:00开始 >
ECFS Scheduler
ECFS 是针对通用场景( Upstream 路线),基于社区主流的 CFS 调度器做优化,核心的优化(设计)点:
引入新的任务调度类型,用于区分在线和离线任务。
优化抢占逻辑,保障在线对离线的抢占。避免离线对在线的不必要抢占
绝对抢占设计
超线程干扰隔离
具体原理暂不展开,请期待后续的 os 系列文章中再说明。
云原生资源 QoS - RUE
RUE (Resource Utilization Enhancement),中文品牌”如意“,是 TencentOS 产品矩阵中一款专为云原生场景下服务器资源 QoS 设计,提升资源利用率,降低运营成本的产品。如意是统一调度分配云上机器的 CPU、IO、网络、内存等资源,相比传统的服务器资源管理方案,如意更适用于云场景,能够显著提升云上机器的资源使用效率,降低云上客户的运营成本,为公有云、混合云、私有云等客户提供资源增值服务。如意的核心技术能做到不同优先级的业务之间不互相干扰,实现资源利用率、资源隔离性能、资源服务质量的高效统一。
架构
RUE 包括如下主要模块:
Cgroup Priority
在内核中引入全局统一的 Pod 优先级概念,同时贯穿于 CPU、Memory、IO、Net 所有资源的处理栈,提供统一的优先级控制。
CPU QoS
基于上一节提及的 TCNS 实现,能实现 CPU 层面的绝对抢占和完美隔离。
Memory QoS
通过在分配和回收路径上的优先级感知,为不同优先级的容器提供不同级别的内存分配 QoS 保障(牺牲低优容器的内存可用性,以保障高优容器的内存 QoS )。其中实现了多个原创特性,整体上能最大程度保障高优容器的内存分配延迟,而这也是 Upstream Kernel 缺乏的关键能力之一。
IO QoS
允许用户将容器从 IO 角度划分成不同优先级,根据优先级分配 IO 资源,保障低优先级容器不会对高优先级容器造成干扰,同时允许低优先级容器使用空闲 IO 资源,从而提升资源利用率。IO 资源 QoS 包含三个方面:带宽 QoS,延迟 QoS 以及回写 QoS。另外,还提供最低带宽保障功能,防止低优饥饿导致可能的优先级反转。
Net QoS
允许用户将服务器上网卡的带宽按照优先级分配给不同的容器,允许低优先级容器使用空闲的带宽资源,同时不会对高优先级容器的网络带宽造成干扰。另外,还提供最低带宽保障功能,防止低优饥饿导致可能的优先级反转。
RUE 的整体结构比较复杂,对 Upstream Kernel 进行了大量的改动和优化,相关特性涉及内容较多而广泛,本文无法一一展开,后续会专文展开逐一讨论,敬请期待。
总体效果
引入全局统一的 Pod 优先级概念,提供统一的优先级控制
适用于多优先级容器( Pod/任务)混合部署,可极大提升资源利用率
Qcon 北京2021-全球软件开发者大会,有相应的 Topic 《腾讯 Kubernetes 大规模离在线混部与内核隔离实践》分享,欢迎围观:【https://qcon.infoq.cn/2021/beijing/presentation/3253】
Quality Monitor
混部场景中,为提升整机资源利用,倾向于最大化 Overcommit。在底层的隔离技术(资源 QoS )保障的前提下,能一定程度保障干扰隔离。但仍面临两个主要挑战:
如何评估 QoS 效果和感知“干扰”?
出现“干扰”后,如何有效排查?
另一方面,上层调度( K8s )也需要基于底层(内核)能提供更有意义的指标(服务质量评估及更细致指标),进行精细化运营,提升混部集群的整体表现,提升混部技术方案的整体竞争力。
现有系统中存在一些分散的、不同维度的统计数据,但:
不够“友好”,对于上层调度( K8s )来说,不能理解,需要一些更有意义的抽象数据,作为“基础”的调度依据。
不够“专业”,对于混部场景,还需要一些针对性的监控数据,K8s可以基于这些数据做更“精细”的运营。
另一方面,现有系统缺乏常态运行的调测手段,能在出现“干扰”(或者高优容器抖动)时,第一时间抓到现场,有效分析定位的手段。现有手段的不足:
多需事后部署( Ftrace/Kprobe 等),但业务抖动可能难以复现,或者瞬时偶现,难以捕捉。
开销大,难以常态化部署。
随 Cgroup V2 一起出现的 PSI 是一种非常好的尝试,一定程度上反应了系统的 Health 状态,但如用于混部场景的 QoS 效果评估,还略显单薄。
TencentOS 设计了Quality Monitor,专用于评估容器各方面的服务质量( QoS ),并提供常态化、低开销、事件触发的监控机制,在出现服务质量下降(不达标)时,可以及时、有效的捕获异常上下文。
Quality Monitor 主要包含两个模块:
Score
服务质量评分,具体定义为:
Per-Prio score = 100 - 因其他优先级( Cgroup )进程干扰(资源抢占)而 Stall 的时间占比
Per-Cg score = 100 - 因其他 Cgroup 进程干扰(资源抢占)而 Stall 的时间占比
注:这里的干扰包括软件和硬件层面的干扰
Monitor Buffer
常态监控干扰和抖动的内存区,当关键指标(依赖于云原生 SLI )不符合预期(超限)时,自动记录相关上下文信息。
总体效果:
提供优先级和 Pod 两个维度的服务质量评分,用于评估容器的服务质量( QoS ) 当出现服务质量下降(干扰)时,可以通过 Monitor Buffer 捕获到异常上下文
云原生 SLI
定义
SLI (Service Level Indicator) 是用于观测 Service level 的指标,比如 Latency、吞吐、错误率等;
SLO 是基于 SLI 指定的目标;
从云原生的角度看,云原生 SLI 可以(狭义的)理解为针对容器的可用于观测 Service level 的指标,即容器视角的的一些关键指标,这也是定义容器 SLO 的基础。
另一方面,现有 Upstream Kernel 在 Cgroup 基本的统计和监控还比较原始和粗糙,仅有一些基本的统计信息,比如 Memory/Cpu 的 Usage 信息,缺乏可用的、容器视角的 SLI 数据采集和抽象。
TencentOS 设计了云原生 SLI,通过在内核中实时的搜集和计算(低开销方式),提供充分的、专业的、不同维度的 SLI 指标,供上层( K8s )使用,用户可基于此定个相应的 SLO。
云原生 SLI 包括如下模块:
CPU SLI
收集并计算 CPU 维度的 SLI,具体包括调度延迟、内核态阻塞延迟、Load、Context-switch 频率等。
Memory SLI
收集并计算 Memory 维度的 SLI,具体包括内存分配延迟、内存分配速度、直接回收延迟、内存Compaction 延迟、内存回收延迟、内存分配失败率等。
IO SLI
收集并计算 IO 维度的 SLI,具体包括 IO 延迟、IO 吞吐、IO 错误率等。
NET SLI
收集并计算网络维度的 SLI,具体包括网络延迟、网络吞吐、IO 错误率等。
总体效果
提供容器级别级别的细粒度的 SLI 指标
K8s 或其他模块(如 Quality Monitor )可以基于相关指标做精细化运营
Cgroupfs
云原生场景中,基于 Namespace、Cgroup 等底层资源隔离技术,做了资源的基础隔离(容器视角),但容器的整体隔离性还非常不完整,其中,/proc、/sys 文件系统中的一些资源统计信息,还没有完整的容器化(或者说 Namespace 化),导致在物理机/虚拟机中的一些常用命令(比如 free / top )在容器中运行时,不能准确展示容器视角的信息(默认展示系统级别的全局信息,比如系统总内存和 free 内存),这也是云原生(容器)场景中一直存在的一类顽疾。
直接原因是因为相关信息尚未容器化,本质原因还是由于容器的隔离性还存在不足。
针对/proc文件系统中关键信息没有容器化的问题,社区推荐的解决方案是:
lxcfs
lxcfs 是针对上述场景而量身定制的一个虚拟文件系统,其底层基于 FUSE 实现了一个用户态的文件系统,提供容器化视角的 /proc 文件系统中的统计信息,还包括一点点 /sys 文件系统的个别信息,实现比较简单直接。
lxcfs 基本解决了在容器中使用常用基础命令( free / top / vmstat等)的困扰,但仍存如下不足:
需要依赖额外的组件 lxcfs,难与容器深度融合,不可控。
用户态基于 FUSE 实现。开销相比内核更大,信息准确度不如内核。
lxcfs 稳定性比较差(据用户反馈),经常出问题:卡死(开销大)、信息获取不到等。
定制能力差,当前的实现完全基于用户态可见的一些基本信息(当前信息还比较有限),如果需要更深层次的定制(基于用户需求),就会遇到能力瓶颈(受限于用户态实现)。
TencentOS 在内核态提供了相应的解决方案,取名为:Cgroupfs
其核心设计为:设计一个新的虚拟文件系统(放置于根文件系统中),其中包含我们需要实现的容器视角的 /proc、/sys 等 fs,其目录结构保持与全局 procfs 和 sysfs 保持一致,以保证对于用户工具的兼容性。实际读取相关文件时,通过 cgroupfs 的读者进程的上下文来动态生成对应的容器信息视图。
目录结构如下所示:
总体效果
内核态容器视角的虚拟机文件系统( /proc,/sys ),隔离全局信息,支持常规命令( top,free,iotop,vmstat 等)
面向 Cgroup V2 设计,统一层次结构
可根据需求做深层次的定制和扩展
TencentOS For Kubernetes
在云原生浪潮下,Kubernetes 作为行业事实标准首当其冲。随着云原生进入深水区,业务也更关注上云后的实际增益,资源利用率与成本也日益被重视。在原有 Kubernetes 体系中,通过 Service QoS Class 和 Priority 可将不同优先级 workload 混部在同一集群中,以增加资源利用率,减少资源运营成本。但这种“用户态”行为受限于 Linux kernel cgroups 设计,天生隔离粒度不足。业务会因混部后资源争抢受损,有时往往得不偿失。
在这种背景下,TencentOS 面向云原生与 Prioirty 的设计,能完美解决这个问题。我们通过将 Kubernetes Service QoS Class 与 TencentOS Priority 一一对应,在内核层原生感知优先级,在底层提供强隔离机制,最大程度保证混部后业务的服务质量。而且这种优先级机制是贯穿在整个 cgroups 子系统中。
腾讯云容器团队已在外部开源了 TKE 发行版 ,该 Feature 会在下个版本支持,用户可持续关注社区动态。
More
除关注云原生之外,TencentOS Server 本身为一款通用服务器 OS,在10余年坚持专注内核的过程中,也开发/定制过很多或大或小的 Features,有关 TencentOS 其他说明、以及代码,如有兴趣,欢迎继续戳如下链接了解:
【https://github.com/Tencent/TencentOS-kernel】
结语
TencentOS 一直在思考、探索自己的云原生之路,旅程已开始,但远未结束!
参考阅读
高可用架构欢迎技术架构领域原创文章,欢迎通过公众号菜单「联系我们」进行投稿。